package org.carabiner.infinitest.depgraph;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;

/**
 * The <code>JavaClass</code> class represents a Java class or interface.
 * 
 * @author <b>Mike Clark</b>
 * @author Clarkware Consulting, Inc.
 * @author <a href="mailto:benrady@gmail.com"Ben Rady</a>
 */

public class JavaClass
{
  private String className;
  private boolean isAbstract;
  private Set<String> classImports;
  private Set<JavaClass> parents;

  public JavaClass(String name)
  {
    className = name;
    isAbstract = false;
    parents = new HashSet<JavaClass>();
    classImports = new HashSet<String>();
  }

  public void setName(String name)
  {
    className = name;
  }

  public String getName()
  {
    return className;
  }

  public void addImport(String classname)
  {
    try
    {
      Class clazz = Class.forName(className);
      if (classname.startsWith("["))
      {
        // Normalize the name if it's weird.
        classname = clazz.getName();
      }
      classImports.add(classname);
    }
    catch (ClassNotFoundException e)
    {
      throw new IllegalArgumentException(classname + " is not on the classpath");
    }
  }

  public boolean isAbstract()
  {
    return isAbstract;
  }

  public void isAbstract(boolean isAbstract)
  {
    this.isAbstract = isAbstract;
  }

  public boolean equals(Object other)
  {

    if (other instanceof JavaClass)
    {
      JavaClass otherClass = (JavaClass) other;
      return otherClass.getName().equals(getName());
    }

    return false;
  }

  public int hashCode()
  {
    return getName().hashCode();
  }

  /**
   * Gets the collection on classes that this class depends on. i.e. the list of this classes
   * children.
   * 
   */
  public Collection<String> getImports()
  {
    return Collections.unmodifiableCollection(classImports);
  }

  /**
   * A parent class is one that depends on this class. i.e. if this class changes, it's parent's
   * behavior may change.
   * 
   */
  public Set<JavaClass> getParents()
  {
    return parents;
  }

  /**
   * A parent class is one that depends on this class. i.e. if this class changes, it's parent's
   * behavior may change.
   * 
   * @param clazz
   */
  public void addParent(JavaClass clazz)
  {
    parents.add(clazz);
  }

  @Override
  public String toString()
  {
    return getName();
  }
}
